define([
    'prettier',
    'prettier-babylon',
    'prettier-postcss',
    'prettier-yaml',
    'prettier-markdown',
    'prettier-html',
    'prettier-typescript',
    'xml-formatter',
    'sql-formatter'
], function(
        prettier,
        _babylon, _postcss, _yaml, _markdown, _html, _typescript,
        xmlFormatter, sqlFormatter) {

    angular.module('app.prettier', [])
    .factory('_prettier', function() {
        const _printer = function(path, options, print) {
            const node = path.getValue();
            if (Array.isArray(node)) {
                return prettier.doc.builders.concat(path.map(print));
            }
            return node.value;
        };

        const _indent = function(options) {
            return options.useTabs ? '\t' : '    '.substring(0, options.tabWidth);
        };

        const _plugins = [
            _babylon,
            _postcss,
            _yaml,
            _markdown,
            _html,
            _typescript,
            {
                parsers: {
                    'xml': {
                        astFormat: 'xml',
                        parse: function(text, parsers, options) {
                            var xmlDoc = xmlFormatter.format(text, {
                                indentation: _indent(options),
                                collapseContent: true,
                                lineSeparator: '\n'
                            });
                            return [{
                                type: 'XMLDocument',
                                value: xmlDoc,
                                range: [0, xmlDoc.length]
                            }];
                        }
                    },
                    'sql': {
                        astFormat: 'sql',
                        parse: function(text, parsers, options) {
                            var sqlDoc = sqlFormatter.format(text, {
                                language: 'sql',
                                indent: _indent(options)
                            });
                            return [{
                                type: 'SQLDocument',
                                value: sqlDoc,
                                range: [0, sqlDoc.length]
                            }];
                        }
                    }
                },
                printers: {
                    'xml': {
                        print: _printer
                    },
                    'sql': {
                        print: _printer
                    }
                }
            }
        ];

        return {
            format: function(text, options) {
                return prettier.format(text, angular.extend({
                    tabWidth: 2,
                    useTabs: false,
                    printWidth: 120,
                    bracketSpacing: true,
                    proseWrap: 'preserve',
                    semi: true,
                    jsxSingleQuote: false,
                    jsxBracketSameLine: false,
                    arrowParens: 'avoid',
                    trailingComma: 'none',
                    htmlWhitespaceSensitivity: 'ignore',
                    insertPragma: false,
                    requirePragma: false,
                    plugins: _plugins
                }, options));
            }
        };
    });
});
